#include "DmMainAfx.h"
#include "xSIMD.h"

namespace
{
	bool bCPUIDChecked = FALSE;
	bool bMMX = FALSE;
	bool bSSE = FALSE;
	bool bSSE2 = FALSE;
}

inline bool CPUIDAvailable()
{
	bool result;
	__asm
	{
		mov edx, 0
		pushfd
		pop eax
		mov ecx, eax
		xor eax, 0x00200000
		push eax
		popfd
		pushfd
		pop eax
		xor ecx, eax
		jz END
		mov edx, 1
END:
		push eax
		popfd
		mov eax, edx
		mov result, al
	}
	return result;
}

inline unsigned int CPUSignature()
{
	unsigned int result;
	__asm
	{
		push ebx
		mov eax, 1
		cpuid
		pop ebx
		mov result, eax
	}
	return result;
}

inline unsigned int CPUFeatures()
{
	unsigned int result;
	__asm
	{
		push ebx
		mov eax, 1
		cpuid
		pop ebx
		mov result, edx
	}
	return result;
}

void xCPUInfo::CheckCPUID(void)
{
    if (bCPUIDChecked) return;
	if (!CPUIDAvailable()) return; // no CPUID available
	unsigned int features = CPUFeatures();
	if (features & 0x800000) bMMX = true; // support MMX
	if (features & 0x2000000) bSSE = true; // support SSE
	if (features & 0x4000000) bSSE2 = true; // support SSE2
    bCPUIDChecked = TRUE;
}

BOOL xCPUInfo::IsSupportMMX(void)
{
	if (!bCPUIDChecked)
	{
		CheckCPUID();
	}
	return bMMX;
}

BOOL xCPUInfo::IsSupportSSE(void)
{
	if (!bCPUIDChecked)
	{
		CheckCPUID();
	}
	return bSSE;
}

BOOL xCPUInfo::IsSupportSSE2(void)
{
	if (!bCPUIDChecked)
	{
		CheckCPUID();
	}
	return bSSE2;
}

